/**
 * 牌桌组件
 */

import { useEffect, useState, useReducer } from 'react'
import { Button, MessagePlugin } from 'tdesign-react'
import PockerItem from './PockerItem'
import { deepCopy, timeSleep } from '@/utils'

type PropsType = {
  playerNumber: number,
  // pockerGroup: PockerType[][],
  // playerPockerIndex: number,
  playerList: PlayerRoleType[],
  // commonPocker: PockerType | undefined
}

const PockerTable = (props: PropsType) => {

  const {
    playerNumber = 10,
    playerList = [],
  } = props

  // 花色
  const suitArray: SuitType[] = ['heart', 'spade', 'club', 'diamond']
  // 点数
  const pockerNumberArray: PockerNumberType[] = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
  // 点数值
  const numberArrayValue = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
  // 牌型数值
  const pockerTypeValue = [60000, 50000, 40000, 30000, 20000, 10000]
  // 发牌间隔
  const dealPockerInterval = 500
  // 底注金额
  const baseAmount = 1000

  // 当前玩家
  const [currentPlayer, setCurrentPlayer] = useState<PlayerRoleType>({ name: '', score: 0, pockerGroup: [], isCurrentPlayer: true })
  // 其他玩家
  const [elsePlayerList, setElsePlayerList] = useState<PlayerRoleType[]>([])
  // 所有卡牌
  const [pockers, setPockers] = useState<PockerType[]>([])
  // 公共牌
  const [commonPocker, setCommonPocker] = useState<PockerType | undefined>(undefined)
  // 是否开牌
  const [isOpened, setIsOpened] = useState(false)
  // 当前下注金额
  const [currentAmount, setCurrentAmount] = useState(baseAmount)
  // 下注总额
  const [totalAmount, setTotalAmount] = useState(0)
  // 强制渲染
  const [, forceUpdate] = useReducer((s) => s + 1, 0)

  useEffect(() => {
    console.log('aaaaaaaaaaaaaaaaaaaaaaaa')
    if (playerNumber) {
      setElsePlayerList(deepCopy(playerList).slice(1, playerNumber))
      setCurrentPlayer(playerList[0])
      setCommonPocker(undefined)
      setCurrentAmount(baseAmount)
    }
  }, [JSON.stringify(playerList)])

  useEffect(() => {
    console.log('totalAmount', totalAmount)
  }, [])

  /**
   * 创建牌堆
   * @returns pockers
   */
  const createPockers = (): PockerType[] => {
    let pockers: PockerType[] = []
    pockerNumberArray.forEach((pockerNumber: PockerNumberType, pockerNumberIndex: number) => {
      suitArray.forEach((suit: SuitType) => {
        pockers.push({
          suit: suit,
          number: pockerNumber,
          isOut: false,
          value: numberArrayValue[pockerNumberIndex]
        })
      })
    })
    return pockers
  }

  /**
   * 洗牌
   */
  const shufflePocker = (pockers: PockerType[]) => {
    if (!pockers || pockers.length === 0) {
      MessagePlugin.error('牌堆为空, 请先拆牌', 2000)
      return []
    }
    return deepCopy(pockers).sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
  }

  /**
   * 发牌
   * 从牌堆中随机抽取 n 组牌，每组三张，n 为玩家数量
   * 发牌逻辑以后修改为每次 n 张，每个玩家一张
   */
  const dealPockerForPlayer = async (pockers: PockerType[]) => {
    if (!pockers || pockers.length === 0) {
      MessagePlugin.error('牌堆为空, 请先拆牌', 2000)
      return
    }
    let _pockers: PockerType[] = deepCopy(pockers)
    let _commonPocker: PockerType | undefined = undefined
    let _currentPlayer = deepCopy(currentPlayer)
    let _elsePlayerList = deepCopy(elsePlayerList)
    let _outNumber = 0
    for (let cardIndex = 0; cardIndex < 3; cardIndex++) {
      for (let playerIndex = 0; playerIndex < playerNumber; playerIndex++) {
        const playerPocker = _pockers[_outNumber]
        _pockers[_outNumber].isOut = true
        _outNumber++
        if (playerIndex === 0) {
          _currentPlayer.pockerGroup.push(playerPocker)
          setCurrentPlayer(_currentPlayer)
          await timeSleep(dealPockerInterval)
          forceUpdate()
        } else {
          _elsePlayerList[playerIndex - 1].pockerGroup.push(playerPocker)
          setElsePlayerList(_elsePlayerList)
          await timeSleep(dealPockerInterval)
          forceUpdate()
        }
      }
    }
    _commonPocker = _pockers[_outNumber]
    _pockers[_outNumber].isOut = true
    for (let playerIndex = 0; playerIndex < playerNumber; playerIndex++) {
      if (playerIndex === 0) {
        _currentPlayer.score -= currentAmount
      } else {
        _elsePlayerList[playerIndex - 1].score -= currentAmount
      }
    }
    setCurrentPlayer(_currentPlayer)
    setElsePlayerList(_elsePlayerList)
    await timeSleep(dealPockerInterval)
    forceUpdate()
    setCommonPocker(_commonPocker)
    setPockers(_pockers)
    setTotalAmount(currentAmount * playerNumber)
  }

  const seePokcer = (index: number) => {
    let _currentPlayer = deepCopy(currentPlayer)
    _currentPlayer.pockerGroup[index].isSeen = true
    setCurrentPlayer(_currentPlayer)
  }

  /**
   * 弃牌不跟
   */
  const getOut = async () => {
    let _currentAmount = currentAmount + baseAmount
    let _totalAmount = totalAmount
    let _elsePlayerList = deepCopy(elsePlayerList)
    _elsePlayerList.forEach((elsePlayer: PlayerRoleType, index: number) => {
      if (elsePlayer.score < 0) {
        _elsePlayerList[index].score = 0
      } else {
        _elsePlayerList[index].score -= baseAmount
        _totalAmount += baseAmount
      }
    })
    setElsePlayerList(_elsePlayerList)
    setCurrentAmount(_currentAmount)
    setTotalAmount(_totalAmount)
    forceUpdate()
    getOpen(_elsePlayerList.length - 1)
  }

  /**
   * 加注
   */
  const addAmount = () => {
    let _currentAmount = currentAmount + baseAmount
    let _totalAmount = totalAmount
    let _currentPlayer = deepCopy(currentPlayer)
    let _elsePlayerList = deepCopy(elsePlayerList)
    _currentPlayer.score -= baseAmount
    _totalAmount += baseAmount
    _elsePlayerList.forEach((elsePlayer: PlayerRoleType) => {
      if (elsePlayer.score < 0) {
        elsePlayer.score = 0
      } else {
        elsePlayer.score -= baseAmount
        _totalAmount += baseAmount
      }
    })
    setCurrentPlayer(_currentPlayer)
    setElsePlayerList(_elsePlayerList)
    setCurrentAmount(_currentAmount)
    setTotalAmount(_totalAmount)
  }

  /**
   * 开牌
   */
  const getOpen = (openPlayerIndex?: number) => {
    let _currentPlayer = deepCopy(currentPlayer)
    let _elsePlayerList = deepCopy(elsePlayerList)
    setIsOpened(true)
    let { isCurrentPlayer, playerIndex, pockerGroup, pockerType } = getMaxPockerPlayer()

    if (isCurrentPlayer) {
      _currentPlayer.score += totalAmount
    } else {
      _elsePlayerList[playerIndex - 1].score += totalAmount
    }
    if (openPlayerIndex === undefined) {
      _currentPlayer.pockerGroup = []
      _currentPlayer.score -= baseAmount
    } else {
      _elsePlayerList[openPlayerIndex as number].score -= baseAmount
    }

    setCurrentPlayer(_currentPlayer)
    setElsePlayerList(_elsePlayerList)
    
    MessagePlugin.success(`赢家是${playerList[playerIndex].name} 牌型为${pockerType} 赢得${totalAmount}积分`, 10 * 1000)
  }

  /**
   * 获取最大牌的玩家
   * 牌的大小为 豹子 > 同花顺 > 金花 > 顺子 > 对子 > 单张
   */
  const getMaxPockerPlayer = () => {
    let _elsePlayerList = deepCopy(elsePlayerList)
    let _allPlayerGroupList: any = []

    for (let i = 0; i < _elsePlayerList.length; i++) {
      if (i === 0) {
        _allPlayerGroupList.push({
          playerIndex: 0,
          ...getPockerGoupType(currentPlayer.pockerGroup, 0)
        })
      }
      _allPlayerGroupList.push({
        playerIndex: i + 1,
        ...getPockerGoupType(_elsePlayerList[i].pockerGroup, 0)
      })
    }

    _allPlayerGroupList.sort((a: any, b: any) => a.cardScore < b.cardScore)
    
    return {
      isCurrentPlayer: _allPlayerGroupList[0].playerIndex == 0,
      playerIndex: _allPlayerGroupList[0].playerIndex,
      pockerGroup: _allPlayerGroupList[0].pockerGroup,
      pockerType: _allPlayerGroupList[0].pockerType,
    }
  }

  /**
   * 判断是否为豹子 牌型值为 60000 最大牌型为 AAA 39            最小牌型为 222 6
   * 判断是否为同花顺 牌型值为 50000 最大牌型为 AKQ 36          最小牌型为 234 9
   * 判断是否为同花 牌型值为 40000 最大牌型为 AKJ 13+12+10 = 35 最小牌型为 235 10
   * 判断是否为顺子 牌型值为 30000 最大牌型为 AKQ 13+12+11 = 36 最小牌型为 234 9
   * 判断是否为对子 牌型值为 20000 最大牌型为 AAK 13+13+12 = 38 最小牌型为 223 7 2 * 10 650
   * 判断是否为单张 牌型值为 10000 最大牌型为 AKJ 13+12+10 = 35 最小牌型为 235 10 为啥要算和，我得看看怎么样才能不超过阈值好吧你继续
   *
   * 计算大小的逻辑为 首先判断牌型值 牌型值的优先级最高，如果牌型值一样则判断牌值 (最大牌 * 牌值) + (中间牌 * 牌值 * 0.01) + (最小牌 * 牌值 * 0.0001)
   * 例如 ['7', '5', 'J']、['7', '2', 'A'] 首先排序得到 ['J', '7' , '5'] ['A', '7', '2']
   * 然后取出对应的牌点数的值 [10, 6, 4], [13, 7, 2]
   * 按照上述计算方法 得到 10 + 0.06 + 0.0004 = 10.0604 和 13 + 0.07 + 0.0002 = 13.0702
   * 可顺利得到大小 顺利个锤子宝宝我看不懂 等你面对面好了嘿嘿好
   * 对子之间的比较 不看最大值，而是对子的大小
   */
  const getPockerGoupType = (pockerGroup: PockerType[], pockerTypeIndex: number) => {
    let _isSameNumber = true
    let _pockerGroup = deepCopy(pockerGroup)
    let cardScore = 0

    _pockerGroup.sort((a: PockerType, b: PockerType) => b.value - a.value)

    for (let i = 0; i < _pockerGroup.length; i++) {
      if (_pockerGroup[0].value !== _pockerGroup[i].value) {
        _isSameNumber = false
      }
      cardScore += (100 ** -i * _pockerGroup[i].value)
    }

    if (_isSameNumber) {
      cardScore += pockerTypeValue[pockerTypeIndex]
      let _pockerType = '豹子' + _pockerGroup[0].number
      return {
        pockerType: _pockerType,
        pockerGroup: _pockerGroup,
        cardScore,
      }
    } else {
      pockerTypeIndex++
      // // 判断是否为顺子，顺子分为同花顺和非同花顺、非顺子又分为同花单张、对子和散牌，非同花只能为对子和散牌
      if (_pockerGroup[1].value + 1 === _pockerGroup[0].value && _pockerGroup[1].value - 1 === _pockerGroup[2].value) {
        if (_pockerGroup[1].suit === _pockerGroup[0].suit && _pockerGroup[1].suit === _pockerGroup[2].suit) {
           // 是顺子且是同花顺
           cardScore += pockerTypeValue[pockerTypeIndex]
           let _pockerType = '同花顺' + _pockerGroup[2].number + '、' + _pockerGroup[1].number + '、' + _pockerGroup[0].number
           return {
             pockerType: _pockerType,
             pockerGroup: _pockerGroup,
             cardScore,
           }
        } else {
          // 是顺子但不是同花顺
          pockerTypeIndex += 2
          let _pockerType = '顺子' + _pockerGroup[2].number + '、' + _pockerGroup[1].number + '、' + _pockerGroup[0].number
          cardScore += pockerTypeValue[pockerTypeIndex]
          return {
            pockerType: _pockerType,
            pockerGroup: _pockerGroup,
            cardScore,
          }
        }
      } else {
        // 不是顺子则可能为同花单张、对子、散牌, 如果是同花则一定不为散牌
        if (_pockerGroup[1].suit === _pockerGroup[0].suit && _pockerGroup[1].suit === _pockerGroup[2].suit) {
          pockerTypeIndex++
          cardScore += pockerTypeValue[pockerTypeIndex]
          let _pockerType = '同花' + _pockerGroup[0].number + '、' + _pockerGroup[1].number + '、' + _pockerGroup[2].number
          return {
            pockerType: _pockerType,
            pockerGroup: _pockerGroup,
            cardScore,
          }
        } else {
          if (_pockerGroup[1].value === _pockerGroup[0].value || _pockerGroup[1].value === _pockerGroup[2].value) {
            pockerTypeIndex += 3
            cardScore += ((_pockerGroup[1].value * 100) + (_pockerGroup[0].value !== _pockerGroup[1].value ? _pockerGroup[0].value : _pockerGroup[2].value))
            cardScore += pockerTypeValue[pockerTypeIndex]
            let _pockerType = '一对' + _pockerGroup[1].number
            return {
              pockerType: _pockerType,
              pockerGroup: _pockerGroup,
              cardScore,
            }
          } else {
            pockerTypeIndex += 4
            cardScore += pockerTypeValue[pockerTypeIndex]
            let _pockerType = '散牌' + _pockerGroup[0].number + '、' + _pockerGroup[1].number + '、' + _pockerGroup[2].number
            return {
              pockerType: _pockerType,
              pockerGroup: _pockerGroup,
              cardScore,
            }
          }
        }
      }
    }
  }

  /**
   * 下一回合
   */
  const nextRound = async () => {
    let _currentPlayer = deepCopy(currentPlayer)
    let _elsePlayerList = deepCopy(elsePlayerList)
    _currentPlayer.pockerGroup = []
    _elsePlayerList.forEach((elsePlayer: PlayerRoleType, index: number) => {
      _elsePlayerList[index].pockerGroup = []
    })
    console.log('_currentPlayer', _currentPlayer)
    console.log('_elsePlayerList', _elsePlayerList)
    setCurrentPlayer(deepCopy(_currentPlayer))
    setElsePlayerList(deepCopy(_elsePlayerList))
    setCurrentAmount(baseAmount)
    setTotalAmount(playerList.length * baseAmount)
    setIsOpened(false)
    setCommonPocker(undefined)
    
    // MessagePlugin.info('正在整理牌桌', 2000)

    let _pockers = deepCopy(pockers)
    for (let i = 0; i < _pockers.length; i++) {
      _pockers[i].isOut = false
    }

    _pockers = shufflePocker(deepCopy(_pockers))
    setPockers(_pockers)
    // await timeSleep(2000)
    // forceUpdate()
    // await timeSleep(2000)
    // dealPockerForPlayer(_pockers)
  }


  return <div className='pocker-table'>
    <div className='pocker-action-buttons'>
      <Button
        className='pocker-action-button pocker-open'
        onClick={() => { setPockers(createPockers()) }}
      >拆牌</Button>
      <Button
        className='pocker-action-button pocker-shuffle'
        onClick={() => { setPockers(shufflePocker(pockers)) }}
      >洗牌</Button>
      <Button
        className='pocker-action-button pocker-deal'
        onClick={() => { dealPockerForPlayer(pockers) }}
      >发牌</Button>
    </div>
    <div className='else-player-area'>
      {elsePlayerList.map((elsePlayer: PlayerRoleType, index: number) => {
        const { pockerGroup = [], rotateDeg = 0 } = elsePlayer
        console.log('pockerGroup', elsePlayerList)
        return <div className='else-player-area-item'
          style={{transform: `rotate(${rotateDeg - 120}deg)`}}
          key={index}
        >
          <div className='pocker-cards'>
            {pockerGroup.map((pocker: PockerType, index: number) => {
              return <PockerItem key={index} pocker={pocker} isPlayer={false} isOpened={isOpened}/>
            })}
          </div>
          <div className='player-score'>{elsePlayer.name}: {elsePlayer.score}</div>
        </div>
      })}
    </div>
    <div className='common-pocker-area'>
      {commonPocker && <>
        <PockerItem pocker={commonPocker} isPlayer={false} isCommonPocker={true} />
        <div className='current-amount'>底注大小：{currentAmount}</div>
        <div className='all-pocker-amount'>下注总额：{totalAmount}</div>
      </>}
    </div>
    <div className='current-player-area'>
      <div className='player-score'>{currentPlayer?.name}: {currentPlayer?.score}</div>
      <div className='pocker-cards'>
        {currentPlayer?.pockerGroup.map((pocker: PockerType, index: number) => {
          return <PockerItem key={index} pocker={pocker} isPlayer={false} onClick={() => { seePokcer(index) }} />
        })}
      </div>
      {commonPocker && <div className='player-action-buttons'>
        <Button className='player-action-button' onClick={getOut}>弃牌不跟</Button>
        <Button className='player-action-button' onClick={addAmount}>加注 x2</Button>
        <Button className='player-action-button' onClick={() => { getOpen() }}>开牌</Button>
        <Button className='player-action-button' onClick={nextRound}>下一回合</Button>
      </div>}
    </div>
  </div>
}

export default PockerTable
